package com.hy.service.impl;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hy.constans.HttpStatus;
import com.hy.domain.FileInfo;
import com.hy.domain.dto.R;
import com.hy.exception.SystemException;
import com.hy.service.FileInfoService;
import com.hy.mapper.FileInfoMapper;
import com.hy.util.SHA1Utils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
* @author hou
* @description 针对表【file_info(上传的文件信息)】的数据库操作Service实现
* @createDate 2023-04-21 14:43:12
*/
@Service
public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo>
    implements FileInfoService{

    @Value("${upload.path}")
    private String basePath;

    /**
     * 保存文件
     * @param file
     * @return
     */
    @Override
    public R saveFile(MultipartFile file) {
//        InputStream in = null;
        try (InputStream in = file.getInputStream();) {
//            in = file.getInputStream();
            String filename = file.getOriginalFilename();
            String sha1 = SHA1Utils.checksumToString(in);
            // 比对数据库
            FileInfo fileInfo = lambdaQuery()
                    .eq(FileInfo::getFileSha1, sha1)
                    .eq(FileInfo::getFileSize, file.getSize())
                    .eq(FileInfo::getFileType, file.getContentType())
                    .one();

            System.out.println("fileInfo = " + fileInfo);
            if (fileInfo == null) {
                // TODO 保存文件
                File dir = new File(basePath);
                if (!dir.exists()) {
                    dir.mkdir();
                }
                // 转存

                fileInfo = new FileInfo();
                String newFileName = UUID.randomUUID().toString(true) + filename.substring(filename.lastIndexOf('.'));
                file.transferTo(new File(basePath + newFileName));
                fileInfo.setFileName(newFileName);
                fileInfo.setFileSha1(sha1);
                fileInfo.setFileType(file.getContentType());
                fileInfo.setFileSize(file.getSize());
                save(fileInfo);
                return R.ok("/file/download/" + newFileName).message("文件上传成功");
            } else {
                // 文件已经存在，直接返回数据
                return R.ok("/file/download/" + fileInfo.getFileName()).message("文件上传成功");
            }

        } catch (Exception e) {
//            return R.fail("文件上传失败");
            throw new SystemException(HttpStatus.ERROR, "文件上传失败");
        }
    }

    /**
     * 获取文件
     * @param fileName 文件名
     * @param response
     * @return
     */
    @Override
    public R getFileByName(String fileName, HttpServletResponse response) {
        try(
            FileInputStream in = new FileInputStream(new File(basePath + fileName));
            ServletOutputStream out = response.getOutputStream()
        ) {
            FileInfo fileInfo = getById(fileName);
            if (fileInfo == null) {
                return R.fail("文件不存在");
            }
            String fileType = fileInfo.getFileType();
//            response.setContentType(fileType);
            byte[] buffer = new byte[4096];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
                out.flush();
            }

        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("获取文件失败");
        }
        return R.ok();
    }
}




